<template>
  <div>
    <div>
      <!-- {{ formData }}
      {{ Storage.get(ACCESS_TOKEN_KEY) }} -->
    </div>
    <!-- 表格列表 -->
    <el-card>
      <!-- 添加 -->
      <el-button type="success" size="small" @click="add">添加文章</el-button>

      <el-table ref="elTableRef" :data="tableData" size="small" style="width: 100%">
        <el-table-column label="序号">
          <template #default="{ $index }">
            {{ $index + 1 }}
          </template>
        </el-table-column>
        <el-table-column label="文章标题">
          <template #default="{ row }">
            <div>
              {{ row.title }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="封面">
          <template #default="{ row }">
            <el-image style="width: 100px; height: 100px" :src="row.cover" />
          </template>
        </el-table-column>
        <el-table-column label="所属分类">
          <template #default="{ row }">
            <div>
              {{ row.category_name }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="所属标签">
          <template #default="{ row }">
            <div>
              {{ findTagNameByTagIds(tags, row.tag_ids) }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="是否删除">
          <template #default="{ row, $index }">
            <div>
              <el-tag :type="row.is_show ? 'success' : 'info'">
                {{ row.is_delete ? "删除（回收站）" : "未删除" }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="添加时间">
          <template #default="{ row }">
            <div>
              {{ formatDate(row.add_date, "YYYY-MM-DD") }}
            </div>
          </template>
        </el-table-column>

        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button type="primary">查看详情</el-button>
            <el-button type="primary">编辑</el-button>
            <el-button type="danger">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div style="margin: 8px 0">
        <!-- total:总记录数,default-page-size:每页显示条数 -->
        <el-pagination
          background
          v-model:current-page="page"
          @current-change="currentChange"
          :default-page-size="pagesize"
          layout="prev, pager, next,total"
          :total="count"
        />
      </div>
    </el-card>

    <!-- 添加、编辑文章的弹框 -->
    <el-dialog
      v-model="isShowDialog"
      width="1200px"
      :title="(operate === 'add' ? '添加' : '编辑') + '分类'"
    >
      <el-form
        ref="ruleFormRef"
        :model="formData"
        style="max-width: 1200px"
        label-width="auto"
        label-position="right"
      >
        <el-form-item label="文章标题">
          <el-input autocomplete="off" placeholder="文章标题" v-model="formData.title" />
        </el-form-item>

        <el-form-item label="封面图">
          <el-upload
            class="avatar-uploader"
            :headers="{ Authorization: Storage.get(ACCESS_TOKEN_KEY) }"
            name="avatar"
            :action="uploadUrl"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="formData.imageUrl" :src="formData.imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>

        <el-form-item label="所属分类">
          <el-select placeholder="请选择所属分类" v-model="formData.category_id">
            <!-- value：改成管理员主键，label:自定义显示名称 -->
            <el-option label="请选择分类" :value="0" />
            <el-option
              v-for="item in categoryList"
              :key="item.category_id"
              :label="item.category_name"
              :value="item.category_id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="所属标签">
          <el-select
            v-model="formData.tag_ids"
            multiple
            placeholder="请选择分类标签"
            style="width: 240px"
          >
            <el-option
              v-for="item in tagOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="内容"></el-form-item>
        <!-- markdown内容容器 -->
        <div id="markdown"></div>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="isShowDialog = false">取消</el-button>
          <el-button type="primary" @click="submitForm()">确认</el-button>
          <el-button type="primary" @click="resetForm(ruleFormRef)">重置reset</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import ArticleAPI, { type Article } from "@/api/system/article.api";
import CategoryAPI, { type Category } from "@/api/system/category.api";
import { formatDate } from "@/utils/index";
import type { FormInstance } from "element-plus";
import Vditor from "vditor";
import { Storage } from "@/utils/storage";
import { ACCESS_TOKEN_KEY } from "@/constants/cache-keys";
import type { UploadProps } from "element-plus";

// 导入样式
import "vditor/dist/index.css";

const UPLOAD_URL = "http://127.0.0.1:7000/api/admin/upload";

const page = ref(1); // 页码
const pagesize = ref(2); // 每页显示条数
const count = ref(0); // 分页的总记录数
const tableData = ref<Article[]>([]);
// 控制弹框显示或隐藏的状态变量
const isShowDialog = ref<boolean>(false);
const ruleFormRef = ref<FormInstance>();
const operate = ref<string>("add"); // edit  add
const categoryList = ref<Category[]>([]);
const uploadUrl = ref<string>(UPLOAD_URL);

// 表单数据 Partial<Article>将article中对象的所有属性转为可选属性
const formData = ref<Partial<Article>>({
  title: "",
  imageUrl: "", // 为了预览
  category_id: 0,
  tag_ids: [],
  content: "",
  cover: "", // 提交给服务器接口
});

const vditor = ref<Vditor | null>(null);

// 标签下拉框列表
const tagOptions = ref([]);

let tags: any[] = []; // 所有的标签数据

// 上传图片成功的回调
const handleAvatarSuccess: UploadProps["onSuccess"] = (response, uploadFile) => {
  console.log("Upload success=>", response);
  // 回显
  formData.value.imageUrl = URL.createObjectURL(uploadFile.raw!);
  // 记录上传成功后的图片路径
  formData.value.cover = response.data.path;
};

// 上传文件的验证规则
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  console.log("beforeAvatarUpload", rawFile);
  let imgMime = ["image/jpeg", "image/png", "image/gif"];
  if (!imgMime.includes(rawFile.type)) {
    ElMessage.error("图片只能是png、jpg、gif格式");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("封面图不能超过 2MB!");
    return false;
  }
  return true;
};

//声明一个函数，用于获取标签字符串的对应标签名;入参 1,2 => java,JDK
let findTagNameByTagIds = (tags: any[], tag_ids: string) => {
  let tag_ids_arr = tag_ids.split(",").map((item) => parseInt(item));
  let temp: string[] = [];
  tag_ids_arr.forEach((tag_id) => {
    let findTag = tags.find((tag) => tag_id === tag.tag_id);
    if (findTag) {
      temp.push(findTag.tag_name);
    }
  });
  return temp.join(",");
};

onMounted(() => {
  getArticle();
  ArticleAPI.getAllTag().then((data) => {
    tags = data;
  });
});

// 提交表单
const submitForm = async () => {
  // 将[1,2] => 1,2
  let tag_ids_str = formData.value.tag_ids.join(",");
  console.log(formData.value);
  console.log(tag_ids_str); //'1,2'

  if (operate.value === "add") {
    await ArticleAPI.addArticle({ ...formData.value, tag_ids_str });
  } else {
    // await CategoryAPI.updCategory(formData.value)
  }

  ElMessage({
    type: "success",
    message: (operate.value === "add" ? "添加" : "编辑") + "分类成功",
  });

  isShowDialog.value = false;
  getArticle();
};

// 初始化富文本编辑器
const initVditor = () => {
  // 初始化富文本编辑器
  vditor.value = new Vditor("markdown", {
    after() {
      // 富文本编辑器已经渲染到真实DOM页面中。
      console.log("富文本编辑器已经渲染到真实DOM页面中");
      // 发送ajax请求，获取数据，vditor.setValue(内容)
    },
    height: 500,
    toolbarConfig: {
      hide: false,
      pin: true,
    },
    outline: {
      enable: true,
      position: "right",
    },
    cache: {
      // 不需要同步到内容到本地存储
      enable: false,
      after(markdown: string) {
        console.log("after=>", markdown);

        // 将markdown源代码模式赋值给状态变量
        formData.value.content = markdown;

        // 固定定位大纲位置
        // let outLineEle = document.querySelector('.vditor-outline')
        // outLineEle.style.position = 'fixed'
        // outLineEle.style.right = '10px'
      },
    },
    upload: {
      url: "http://127.0.0.1:4000/api/admin/upload",
      fieldName: "avatar",
      accept: "image/*",
      // 上传成功的回调
      success(editor: HTMLPreElement, msg: string) {
        let result = JSON.parse(msg);
        let photoUrl = result.data.server_url + result.data.path;
        if (vditor.value) {
          // 插入光标位置
          vditor.value.insertValue(`![](${photoUrl})`);
        }
      },
      headers: {
        // JWT token
        Authorization: Storage.get(ACCESS_TOKEN_KEY),
      },
    },
  });
  // 重置markdown内容
  console.log("vditor:", vditor.value);
  // vditor.value.setValue('默认值')
};

// 重置表单
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
};

// 添加文章弹出表单
const add = async () => {
  operate.value = "add";
  // 恢复默认值（要重置表单数据）
  resetForm(ruleFormRef.value);

  // 1. 获取分类列表接口数据
  categoryList.value = await CategoryAPI.getAllCategory();
  let tags = await ArticleAPI.getAllTag();
  tags = tags.map(({ tag_id, tag_name }) => {
    let tag = { value: tag_id, label: tag_name };
    return tag;
  });
  tagOptions.value = tags;
  console.log("tagOptions=>", tagOptions);
  // 2. 显示添加表单
  isShowDialog.value = true;

  // 更待DOM是最新的
  await nextTick();
  // 初始化富文本编辑器
  initVditor();

  setTimeout(() => {
    // 重置markdown内容
    vditor.value!.setValue("");
  }, 100);
};

// 获取文章
const getArticle = async () => {
  let result = await ArticleAPI.fetchArticle({ page: page.value, pagesize: pagesize.value });
  tableData.value = result.article;
  count.value = result.count;
};

// 点击分页，发送请求
const currentChange = () => {
  getArticle();
};
</script>

<style scoped>
.avatar-uploader .avatar {
  display: block;
  width: 178px;
  height: 178px;
}
</style>

<style>
.avatar-uploader .el-upload {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  width: 178px;
  height: 178px;
  font-size: 28px;
  color: #8c939d;
  text-align: center;
}
</style>
